/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.pku.hawk.cloud.util;

import edu.pku.hawk.cloud.xenapi.APIVersion;
import edu.pku.hawk.cloud.xenapi.Connection;
import edu.pku.hawk.cloud.xenapi.Host;
import edu.pku.hawk.cloud.xenapi.HostMetrics;
import edu.pku.hawk.cloud.xenapi.Pool;
import edu.pku.hawk.cloud.xenapi.SR;
import edu.pku.hawk.cloud.xenapi.Session;
import edu.pku.hawk.cloud.xenapi.Task;
import edu.pku.hawk.cloud.xenapi.Types;
import edu.pku.hawk.cloud.xenapi.VM;
import edu.pku.hawk.cloud.xenapi.VMGuestMetrics;
import edu.pku.hawk.cloud.xenapi.VMMetrics;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 *
 * @author Administrator
 */
public class XenUtil {

    protected static Connection connection;

    public static void connect(String masterIP, String userName, String password) {
        try {
            connection = new Connection(new URL("http://" + masterIP));
            Session.loginWithPassword(connection, userName, password, APIVersion.latest().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected static SR getDefaultSR() throws Exception {
        Set<Pool> pools = Pool.getAll(connection);
        Pool pool = (pools.toArray(new Pool[0]))[0];
        return pool.getDefaultSR(connection);
    }

    /**
     * Given a task in progress, sleeps until it completes, waking to print status reports periodically.
     */
    protected static void waitForTask(Connection c, Task task, int delay) throws Exception {
        while (task.getStatus(c) == Types.TaskStatusType.PENDING) {
            Thread.sleep(delay);
        }
    }
    /* Assert that a task has succeeded. Throw an exception if not */

    private static void checkForSuccess(Task task) throws Exception {
        if (task.getStatus(connection) == Types.TaskStatusType.SUCCESS) {
        } else {
            throw new Exception("Task failed! Task record:\n" + task.getRecord(connection));
        }
    }

    public static VM createVMAsync(String masterIP, String tplUuid, String newvmname) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        VM newVm = null;
        try {
            VM template = VM.getByUuid(connection, tplUuid);

            /* Clone the template */
            Task cloning = template.createCloneAsync(connection, newvmname);
            waitForTask(connection, cloning, 500);
            checkForSuccess(cloning);
            newVm = Types.toVM(cloning, connection);
            System.out.println("New VM clone: " + newVm.getNameLabel(connection));

            /* Find a storage repository */
            SR defaultSR = getDefaultSR();
            System.out.println("Default SR: " + defaultSR.getNameLabel(connection));

            /* Put the SR uuid into the provision XML */
            Map<String, String> otherConfig = newVm.getOtherConfig(connection);

            String disks = otherConfig.get("disks");
            disks = disks.replace("sr=\"\"", "sr=\"" + defaultSR.getUuid(connection) + "\"");
            otherConfig.put("disks", disks);

            newVm.setOtherConfig(connection, otherConfig);

            /* Now provision the disks */
            System.out.println("provisioning... ");
            Task provisioning = newVm.provisionAsync(connection);
            waitForTask(connection, provisioning, 5000);
            checkForSuccess(provisioning);
            System.out.println("provisioned");

            /* Should have done the trick. Let's see if it starts. */
            System.out.println("Starting new VM.....");
            Task t = newVm.startAsync(connection, false, false);
            waitForTask(connection, t, 250);
            checkForSuccess(t);
            System.out.println("started");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
        return newVm;

    }

    public static Map createVm(String masterIP, String tplUuid, String newvmname, float memory) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        VM newVm = null;
        String ip = null;
        Map result = new HashMap();
        String vmUuid = null;
        String hostName = null;
        try {
            VM template = VM.getByUuid(connection, tplUuid);

            /* Clone the template */
            Task cloning = template.createCloneAsync(connection, newvmname);
            waitForTask(connection, cloning, 500);
            checkForSuccess(cloning);
            newVm = Types.toVM(cloning, connection);
            System.out.println("New VM clone: " + newVm.getNameLabel(connection));

            /* Find a storage repository */
            SR defaultSR = getDefaultSR();
            System.out.println("Default SR: " + defaultSR.getNameLabel(connection));
            System.out.println("1");
            /* Put the SR uuid into the provision XML */
            Map<String, String> otherConfig = newVm.getOtherConfig(connection);
            String disks = otherConfig.get("disks");
            if (disks != null) {
                disks = disks.replace("sr=\"\"", "sr=\"" + defaultSR.getUuid(connection) + "\"");
                otherConfig.put("disks", disks);
            } else {
//                disks = "<provision><disk device=\"0\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                disks = "<provision><disk device=\"1\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                otherConfig.put("disks", disks);
            }
            System.out.println(disks);


            System.out.println("2");
            newVm.setOtherConfig(connection, otherConfig);

            /* Now provision the disks */
            System.out.println("provisioning... ");
            Task provisioning = newVm.provisionAsync(connection);
            waitForTask(connection, provisioning, 5000);
            checkForSuccess(provisioning);
            System.out.println("provisioned");

            /* Should have done the trick. Let's see if it starts. */
            System.out.println("Starting new VM.....");
            Task t = newVm.startAsync(connection, false, false);
            waitForTask(connection, t, 5000);
            checkForSuccess(t);
            System.out.println("started");
            printPowerState(newVm);
            newVm.setMemoryDynamicMax(connection, (long) memory * 1048576);


            for (int i = 0; i < 50; i++) {
                System.out.println("i" + i);
                ip = getVmIP(masterIP, newVm);
                if (ip != null) {
                    break;
                }
                Thread.sleep(10000);
            }
            vmUuid = newVm.getUuid(connection);
            Host host = newVm.getResidentOn(connection);
            hostName = host.getNameLabel(connection);
            System.out.println("ip:" + ip);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
        result.put("IP", ip);
        result.put("UUID", vmUuid);
        result.put("HOST_NAME", hostName);
        return result;
    }

    public static Map createVmOn(String masterIP, String tplUuid, String newvmname, float memory, String hostUuid) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        VM newVm = null;
        String ip = null;
        Map result = new HashMap();
        String vmUuid = null;
        try {
            VM template = VM.getByUuid(connection, tplUuid);

            /* Clone the template */
            Task cloning = template.createCloneAsync(connection, newvmname);
            waitForTask(connection, cloning, 500);
            checkForSuccess(cloning);
            newVm = Types.toVM(cloning, connection);
            System.out.println("New VM clone: " + newVm.getNameLabel(connection));

            /* Find a storage repository */
            SR defaultSR = getDefaultSR();
            System.out.println("Default SR: " + defaultSR.getNameLabel(connection));
            System.out.println("1");
            /* Put the SR uuid into the provision XML */
            Map<String, String> otherConfig = newVm.getOtherConfig(connection);
            String disks = otherConfig.get("disks");
            if (disks != null) {
                disks = disks.replace("sr=\"\"", "sr=\"" + defaultSR.getUuid(connection) + "\"");
                otherConfig.put("disks", disks);
            } else {
//                disks = "<provision><disk device=\"0\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                disks = "<provision><disk device=\"1\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                otherConfig.put("disks", disks);
            }
            System.out.println(disks);


            System.out.println("2");
            newVm.setOtherConfig(connection, otherConfig);

            /* Now provision the disks */
            System.out.println("provisioning... ");
            Task provisioning = newVm.provisionAsync(connection);
            waitForTask(connection, provisioning, 5000);
            checkForSuccess(provisioning);
            System.out.println("provisioned");

            /* Should have done the trick. Let's see if it starts. */
            System.out.println("Starting new VM.....");
            Host host = Host.getByUuid(connection, hostUuid);
            Task t = newVm.startOnAsync(connection, host, Boolean.FALSE, Boolean.TRUE); //startAsync(connection, false, false);
            waitForTask(connection, t, 5000);
            checkForSuccess(t);
            System.out.println("started");
            printPowerState(newVm);
            newVm.setMemoryDynamicMax(connection, (long) memory * 1048576);


            for (int i = 0; i < 50; i++) {
                System.out.println("i" + i);
                ip = getVmIP(masterIP, newVm);
                if (ip != null) {
                    break;
                }
                Thread.sleep(10000);
            }
            vmUuid = newVm.getUuid(connection);
            System.out.println("ip:" + ip);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
        result.put("IP", ip);
        result.put("UUID", vmUuid);
        return result;
    }

    public static Map createVmOnByName(String masterIP, String tplUuid, String newvmname, float memory, String hostName) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        VM newVm = null;
        String ip = null;
        Map result = new HashMap();
        String vmUuid = null;
        try {
            VM template = VM.getByUuid(connection, tplUuid);

            /* Clone the template */
            Task cloning = template.createCloneAsync(connection, newvmname);
            waitForTask(connection, cloning, 500);
            checkForSuccess(cloning);
            newVm = Types.toVM(cloning, connection);
            System.out.println("New VM clone: " + newVm.getNameLabel(connection));

            /* Find a storage repository */
            SR defaultSR = getDefaultSR();
            System.out.println("Default SR: " + defaultSR.getNameLabel(connection));
            System.out.println("1");
            /* Put the SR uuid into the provision XML */
            Map<String, String> otherConfig = newVm.getOtherConfig(connection);
            String disks = otherConfig.get("disks");
            if (disks != null) {
                disks = disks.replace("sr=\"\"", "sr=\"" + defaultSR.getUuid(connection) + "\"");
                otherConfig.put("disks", disks);
            } else {
//                disks = "<provision><disk device=\"0\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                disks = "<provision><disk device=\"1\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                otherConfig.put("disks", disks);
            }
            System.out.println(disks);


            System.out.println("2");
            newVm.setOtherConfig(connection, otherConfig);

            /* Now provision the disks */
            System.out.println("provisioning... ");
            Task provisioning = newVm.provisionAsync(connection);
            waitForTask(connection, provisioning, 5000);
            checkForSuccess(provisioning);
            System.out.println("provisioned");

            /* Should have done the trick. Let's see if it starts. */
            System.out.println("Starting new VM.....");
            Set hostset = Host.getByNameLabel(connection, hostName);
            Host host = null;
            Iterator hostIterator = hostset.iterator();
            while (hostIterator.hasNext()) {
                host = (Host) hostIterator.next();
            }

            Task t = newVm.startOnAsync(connection, host, Boolean.FALSE, Boolean.TRUE); //startAsync(connection, false, false);
            waitForTask(connection, t, 5000);
            checkForSuccess(t);
            System.out.println("started");
            printPowerState(newVm);
            newVm.setMemoryDynamicMax(connection, (long) memory * 1048576);


            for (int i = 0; i < 50; i++) {
                System.out.println("i" + i);
                ip = getVmIP(masterIP, newVm);
                if (ip != null) {
                    break;
                }
                Thread.sleep(10000);
            }
            vmUuid = newVm.getUuid(connection);
            System.out.println("ip:" + ip);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
        result.put("VM_IP", ip);
        result.put("VM_UUID", vmUuid);
        return result;
    }

    public static void startVm(String masterIP, String vmUuid) {
        try {
            connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
            VM chosen = VM.getByUuid(connection, vmUuid);
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.start(connection, false, true);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static void startVmByName(String masterIP, String vmName) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {

            Set vmset = VM.getByNameLabel(connection, vmName);
            VM chosen = null;
            Iterator iterator = vmset.iterator();
            while (iterator.hasNext()) {
                chosen = (VM) iterator.next();
            }
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.start(connection, false, true);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static void startVmOn(String masterIP, String vmUuid, String hostUuid) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {

            VM chosen = VM.getByUuid(connection, vmUuid);
            Host host = Host.getByUuid(connection, hostUuid);
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.startOn(connection, host, Boolean.FALSE, Boolean.TRUE);//start(connection, false, true);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static void startVmOnByName(String masterIP, String vmName, String hostName) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {
            Set vmset = VM.getByNameLabel(connection, vmName);
            VM chosen = null;
            Iterator iterator = vmset.iterator();
            while (iterator.hasNext()) {
                chosen = (VM) iterator.next();
            }
            Set hostset = Host.getByNameLabel(connection, hostName);
            Host host = null;
            Iterator hostIterator = hostset.iterator();
            while (hostIterator.hasNext()) {
                host = (Host) hostIterator.next();
            }
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.startOn(connection, host, Boolean.FALSE, Boolean.TRUE);//start(connection, false, true);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static void stopVm(String masterIP, String vmUuid) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {

            VM chosen = VM.getByUuid(connection, vmUuid);
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.cleanShutdown(connection);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static void stopVmByName(String masterIP, String vmName) {
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {

            Set vmset = VM.getByNameLabel(connection, vmName);
            VM chosen = null;
            Iterator iterator = vmset.iterator();
            while (iterator.hasNext()) {
                chosen = (VM) iterator.next();
            }
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.cleanShutdown(connection);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static String resumeVm(String masterIP, String vmUuid) {
        String ip = null;
        try {
            connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
            VM chosen = VM.getByUuid(connection, vmUuid);
            if (chosen == null) {
                System.out.println("Cannot find the VM! Please check the Uuid!.");
            } else {
                System.out.println("choseVM:" + chosen.getNameLabel(connection));
                printPowerState(chosen);
                chosen.resume(connection, false, true);
                printPowerState(chosen);
                ip = getVmIP(masterIP, chosen);
                printPowerState(chosen);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
        return ip;
    }

//    public static void createVmFromTemplate(String masterIP, String tplUuid, String vmName) {
//        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
//        try {
//            VM vmTemplate = VM.getByUuid(connection, tplUuid);
//            if (vmTemplate == null) {
//                System.out.println("Cannot find the Template! Please check the Uuid!.");
//            } else {
//                System.out.println("choseTemplate:" + vmTemplate.getNameLabel(connection));
//                VM cloneVM = vmTemplate.createClone(connection, vmName);
//                cloneVM.setNameDescription(connection, "Created at " + new Date().toString() + "by LLQ");
//                cloneVM.provision(connection);
//                cloneVM.start(connection, Boolean.FALSE, Boolean.TRUE);
//                printPowerState(cloneVM);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    public static void setVmMemoryDynamicMax(String masterIP, String vmUuid, float memoryDynamicMax) {
        try {
            connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
            VM vmToReset = VM.getByUuid(connection, vmUuid);
            vmToReset.setMemoryDynamicMax(connection, (long) memoryDynamicMax * 1048576);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void migrateVm(String masterIP, String vmUuid, String destHostUuid, Boolean live) {
        try {
            connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
            VM vmToMigrate = VM.getByUuid(connection, vmUuid);
            Host destHost = Host.getByUuid(connection, destHostUuid);
            Map<String, String> options = new HashMap();
            options.put("live", live.toString());
            vmToMigrate.poolMigrate(connection, destHost, options);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    private static void printPowerState(VM vm) {
        try {
            System.out.println("VM" + vm.getNameLabel(connection) + " powerstate: " + vm.getPowerState(connection));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected static void disconnect() {
        System.out.println("disposing connection");
        try {
            Session.logout(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void testGetDefaultSR() {
        connect("192.168.0.161", CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {
            SR defaultSR = getDefaultSR();
            System.out.println("Default SR: " + defaultSR.getNameLabel(connection));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static String getVmIP(String masterIP, VM vm) {
        String ip = null;
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {
            VM.Record rc = vm.getRecord(connection);
            if (rc == null) {
                System.out.println("rc is null");
            } else {
                System.out.println("rc not null");
            }
            VMGuestMetrics vmGuestMetrics = vm.getGuestMetrics(connection);
            Map networks = vmGuestMetrics.getNetworks(connection);
            if (networks == null) {
                System.out.println("networks is null");
            } else {
                System.out.println("networks not null");
            }
            Iterator iterator = networks.entrySet().iterator();
            System.out.println(iterator.hasNext());
            System.out.println("getting ip****");
            while (iterator.hasNext()) {
                System.out.println("iterator.hasNext()");
                Map.Entry e = (Map.Entry) iterator.next();
                String ipTemp = (String) e.getValue();
                System.out.println("ipTemp:" + ipTemp);
                if (!ipTemp.isEmpty()) {
                    ip = ipTemp;
                    break;
//                    System.out.println("value:" + ipTemp);
                }
            }
        } catch (Exception e) {
//            e.printStackTrace();
        }
        System.out.println(ip);
        return ip;
    }

    public static void testGetIP() {
        String ip = null;
        connect("192.168.0.161", CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {
            VM vm = VM.getByUuid(connection, "28c691fe-8224-d76f-2f69-a002a702498c");
            VM.Record rc = vm.getRecord(connection);
            VMGuestMetrics vmGuestMetrics = vm.getGuestMetrics(connection);
            Map networks = vmGuestMetrics.getNetworks(connection);
            Iterator iterator = networks.entrySet().iterator();
            System.out.println("getting ip----------------");
            while (iterator.hasNext()) {
                Map.Entry e = (Map.Entry) iterator.next();
//                System.out.println("key:" + e.getKey());
                String ipTemp = (String) e.getValue();
                System.out.println(ipTemp);
                if (ipTemp.contains("192.168")) {
                    ip = ipTemp;
                    break;
//                    System.out.println("value:" + ipTemp);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(ip);
    }

    public static void testSetMem() {
        try {
            connect("192.168.0.161", CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
            VM vmToReset = VM.getByUuid(connection, "28c691fe-8224-d76f-2f69-a002a702498c");//vm001
            vmToReset.setMemoryDynamicMax(connection, (long) 512 * 1048576);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testCreateVM() {
        String masterIP = "192.168.0.161";
//        String tplUuid = "0108f5a0-54e6-dab9-471f-25ae528416fe";//windows tpl
        String tplUuid = "9fe9c9ad-1aee-78d1-8eeb-5275f85df98d";//
        String newvmname = "CentOS 5.3 _vm007";
        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        VM newVm = null;
        try {
            VM template = VM.getByUuid(connection, tplUuid);

            /* Clone the template */
            Task cloning = template.createCloneAsync(connection, newvmname);
            waitForTask(connection, cloning, 500);
            checkForSuccess(cloning);
            newVm = Types.toVM(cloning, connection);
            System.out.println("New VM clone: " + newVm.getNameLabel(connection));

            /* Find a storage repository */
            SR defaultSR = getDefaultSR();
            System.out.println("Default SR: " + defaultSR.getNameLabel(connection));
            System.out.println("1");
            /* Put the SR uuid into the provision XML */
            Map<String, String> otherConfig = newVm.getOtherConfig(connection);
            String disks = otherConfig.get("disks");
            if (disks != null) {
                disks = disks.replace("sr=\"\"", "sr=\"" + defaultSR.getUuid(connection) + "\"");
                otherConfig.put("disks", disks);
            } else {
//                disks = "<provision><disk device=\"0\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                disks = "<provision><disk device=\"1\" size=\"8589934592\" sr=\"" + defaultSR.getUuid(connection) + "\" bootable=\"true\" type=\"system\"/></provision>";
//                otherConfig.put("disks", disks);
            }
            System.out.println(disks);


            System.out.println("2");
            newVm.setOtherConfig(connection, otherConfig);

            /* Now provision the disks */
            System.out.println("provisioning... ");
            Task provisioning = newVm.provisionAsync(connection);
            waitForTask(connection, provisioning, 5000);
            checkForSuccess(provisioning);
            System.out.println("provisioned");

            /* Should have done the trick. Let's see if it starts. */
            System.out.println("Starting new VM.....");
            Task t = newVm.startAsync(connection, false, false);
            waitForTask(connection, t, 5000);
            checkForSuccess(t);
            System.out.println("started");
            printPowerState(newVm);
            newVm.setMemoryDynamicMax(connection, (long) 611 * 1048576);

            String ip = null;
            for (int i = 0; i < 50; i++) {
                System.out.println("i" + i);
                ip = getVmIP(masterIP, newVm);
                if (ip != null) {
                    break;
                }
                Thread.sleep(10000);
            }
            System.out.println("ip:" + ip);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            disconnect();
        }
    }

    public static void testSetCPU() {
        try {
            connect("192.168.0.161", CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
            VM vmToReset = VM.getByUuid(connection, "28c691fe-8224-d76f-2f69-a002a702498c");//vm001
            System.out.println("getVCPUsMax:" + vmToReset.getVCPUsMax(connection));
            vmToReset.setVCPUsMax(connection, (long) 1);

            System.out.println("getVCPUsMax:" + vmToReset.getVCPUsMax(connection));
            System.out.println("getVCPUsAtStartup:" + vmToReset.getVCPUsAtStartup(connection));
            vmToReset.setVCPUsNumberLive(connection, (long) 1);
            Map vcpuParam = vmToReset.getVCPUsParams(connection);
            Iterator iterator = vcpuParam.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry o = (Entry) iterator.next();
                System.out.println("KEY:" + o.getKey() + ";VALUE:" + o.getValue());
            }

//            //设置CPU优先级
//            vcpuParam.put("weight", "1024");
//            vmToReset.setVCPUsParams(connection, vcpuParam);
//            vcpuParam = vmToReset.getVCPUsParams(connection);
//             iterator = vcpuParam.entrySet().iterator();
//            while(iterator.hasNext()){
//               Entry o = (Entry)iterator.next();
//               System.out.println("KEY:" + o.getKey() + ";VALUE:" + o.getValue());
//            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testGetMetrics() {
        connect(CloudCfg.POOL_MASTER_IP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
        try {
            Host host = Host.getByUuid(connection, "58405bd8-6724-4047-af3c-9b341fbdc9fd");
//            Set hostCap = host.getCapabilities(connection);
//            Iterator hostCapIterator = hostCap.iterator();
//            while (hostCapIterator.hasNext()) {
//                System.out.println("getCapabilities:" + hostCapIterator.next());
//            }
            System.out.println("host.getAddress:" + host.getAddress(connection));
//System.out.println("host.getSystemStatusCapabilities:"+host.getSystemStatusCapabilities(connection));
            System.out.println("host.getHostname:" + host.getHostname(connection));
            HostMetrics hostMetrics = host.getMetrics(connection);
            System.out.println("hostMetrics.getMemoryFree(connection):" + hostMetrics.getMemoryFree(connection));
            System.out.println("hostMetrics.getMemoryTotal(connection):" + hostMetrics.getMemoryTotal(connection));


            VM vm = VM.getByUuid(connection, "be3c9408-9a86-86d8-e56f-fd92d366f9c4");//vm001
            printPowerState(vm);
            VMGuestMetrics vmGuestMetrics = vm.getGuestMetrics(connection);
            System.out.println("vmGuestMetrics.getRecord(connection).memory.size():" + vmGuestMetrics.getRecord(connection).memory.size());
            System.out.println("vmGuestMetrics:getMemory:" + vmGuestMetrics.getMemory(connection).size());
            VMMetrics metrics = vm.getRecord(connection).metrics;
            Set stateSet = metrics.getState(connection);
            System.out.println("stateSetSize:" + stateSet.size());
            Iterator stateIterator = stateSet.iterator();
            while (stateIterator.hasNext()) {
                System.out.println("state:" + stateIterator.next());
            }
            System.out.println("getLastUpdated:" + metrics.getLastUpdated(connection));
            System.out.println("getMemoryActual:" + metrics.getMemoryActual(connection) / (1024 * 1024));
            System.out.println("getVCPUsUtilisation:" + metrics.getVCPUsUtilisation(connection));
            System.out.println("metrics.getRecord(connection).memoryActual:" + metrics.getRecord(connection).memoryActual / (1024 * 1024));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
//        XenUtil.startVmOn("192.168.0.161",  "28c691fe-8224-d76f-2f69-a002a702498c",  "d597a3d7-f929-4ca9-9b23-564b41de2040");//CentOS 5.3 _vm001
//        XenUtil.startVmByName("192.168.0.161", "CentOS 5.3 _vm001");
        XenUtil.testGetMetrics();
        //        XenUtil.testSetCPU();
//        String masterIP = "192.168.0.161";
//        String tplUuid = "1b309717-8723-9d52-63f0-2ab2c9cdd28b";//CentOS 5.3_Template
//        String newvmname = "CentOS 5.3 _vm007";
//        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
//        try {
//            VM newVm = VM.getByUuid(connection, "28c691fe-8224-d76f-2f69-a002a702498c");
//            Map<String, String> otherConfig = newVm.getOtherConfig(connection);
//            System.out.println(otherConfig.size());
//
//            Iterator iterator = otherConfig.entrySet().iterator();
//            while (iterator.hasNext()) {
//                Map.Entry e = (Map.Entry) iterator.next();
//                System.out.println("key:" + e.getKey());
//                System.out.println("value:" + e.getValue());
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

//        String masterIP = "192.168.0.161";
//        String tplUuid = "0108f5a0-54e6-dab9-471f-25ae528416fe";//Windows_XP_SP3 _TPL
//        String newvmname = "CentOS 5.3 _vm007";
//        connect(masterIP, CloudCfg.OS_USER, CloudCfg.OS_PASSWORD);
//        try {
//            Set<VM> vmSet = VM.getAll(connection);
//            Iterator vmI = vmSet.iterator();
//            while (vmI.hasNext()) {
//                VM newVm = (VM)vmI.next();
//                System.out.println("######vm:"+ newVm.getNameLabel(connection));
//                Map<String, String> otherConfig = newVm.getOtherConfig(connection);
//                System.out.println(otherConfig.size());
//
//                Iterator iterator = otherConfig.entrySet().iterator();
//                while (iterator.hasNext()) {
//                    Map.Entry e = (Map.Entry) iterator.next();
//                    System.out.println("key:" + e.getKey() + ";value:" + e.getValue());
//                }
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }
}
